package com.example.backstage.service.Impl;


import com.example.backstage.dao.*;
import com.example.backstage.service.IOrderService;
import com.example.backstage.vo.OrderVo;
import com.example.backstage.vo.OrderItemVo;
import com.example.backstage.vo.ShippingVo;
import com.example.gok_mall.constUtil.ConstUtil;
import com.example.gok_mall.constUtil.DateTimeUtil;
import com.example.gok_mall.entity.*;
import com.example.gok_mall.reponseData.ResultData;
import com.example.gok_mall.util.BigDecimalUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Random;


@Slf4j
@Service
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderItemDao orderItemDao;

    @Autowired
    private CartDao cartDao;

    @Autowired
    private ShippingDao shippingDao;

    @Autowired
    private ProductDao productDao;


    public ResultData createOrder(Integer userId, Integer shippingId) {
        //从购物车中获取数据
        List<Cart> cartList = cartDao.selectCheckedCartByUserId(userId);
        //计算这个订单的总价
        ResultData resultData = this.getCartOrderItem(userId, cartList);
        if (!resultData.isSuccess()) {
            return resultData;
        }
        List<OrderItem> orderItemList = (List<OrderItem>) resultData.getData();
        BigDecimal payment = this.getOrderTotalPrice(orderItemList);

        //生成订单
        Order order = this.assembleOrder(userId, shippingId, payment);
        if (order == null) {
            return ResultData.fail("生成订单错误");
        }
        if (CollectionUtils.isEmpty(orderItemList)) {
            return ResultData.fail("购物车为空");
        }
        for (OrderItem orderItem : orderItemList) {
            orderItem.setOrderNo(order.getOrderNo());
        }

        //mybatis 批量插入
        orderItemDao.batchInsert(orderItemList);

        //生成成功，减少库存
        this.reduceProductStock(orderItemList);

        //清除购物车
        this.cleanCart(cartList);

        //返回数据给前端
        OrderVo orderVo = assembleOrderVo(order, orderItemList);
        return ResultData.createData(orderVo);

    }

    //组装返回给前端的数据
    private OrderVo assembleOrderVo(Order order, List<OrderItem> orderItemList) {
        OrderVo orderVo = new OrderVo();
        orderVo.setOrderNo(order.getOrderNo());
        orderVo.setPayment(order.getPayment());
        orderVo.setPaymentType(order.getPaymentType());
        orderVo.setPaymentTypeDesc(ConstUtil.PaymentTypeEnum.codeOf(order.getPaymentType()).getValue());
        orderVo.setPostage(order.getPostage());
        orderVo.setStatus(order.getStatus());
        orderVo.setStatusDesc(ConstUtil.OrderStatusEnum.codeOf(order.getStatus()).getValue());

        orderVo.setShippingId(order.getShippingId());
        Shipping shipping = shippingDao.selectByPrimaryKey(order.getShippingId());
        if (shipping != null) {
            orderVo.setReceiverName(shipping.getReceiverName());
            orderVo.setShippingVo(assembleShippingVo(shipping));
        }

        orderVo.setPaymentTime(DateTimeUtil.dateToStr(order.getPaymentTime()));
        orderVo.setSendTime(DateTimeUtil.dateToStr(order.getSendTime()));
        orderVo.setEndTime(DateTimeUtil.dateToStr(order.getEndTime()));
        orderVo.setCreateTime(DateTimeUtil.dateToStr(order.getCreateTime()));
        orderVo.setCloseTime(DateTimeUtil.dateToStr(order.getCloseTime()));

        //orderVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));

        List<OrderItemVo> orderItemVoList = Lists.newArrayList();
        for (OrderItem orderItem : orderItemList) {
            OrderItemVo orderItemVo = assembleOrderItemVo(orderItem);
            orderItemVoList.add(orderItemVo);
        }

        orderVo.setOrderItemVoList(orderItemVoList);

        return orderVo;
    }

    //将订单详情orderItem中的数据组合到orderItemVo中
    private OrderItemVo assembleOrderItemVo(OrderItem orderItem) {
        OrderItemVo orderItemVo = new OrderItemVo();
        orderItemVo.setOrderNo(orderItem.getOrderNo());
        orderItemVo.setProductId(orderItem.getProductId());
        orderItemVo.setProductName(orderItem.getProductName());
        orderItemVo.setProductImage(orderItem.getProductImage());
        orderItemVo.setCurrentUnitPrice(orderItem.getCurrentUnitPrice());
        orderItemVo.setQuantity(orderItem.getQuantity());
        orderItemVo.setTotalPrice(orderItem.getTotalPrice());

        orderItemVo.setCreateTime(DateTimeUtil.dateToStr(orderItem.getCreateTime()));
        return orderItemVo;
    }

    //将shipping中的数据装到ShippingVo里面
    private ShippingVo assembleShippingVo(Shipping shipping) {
        ShippingVo shippingVo = new ShippingVo();
        shippingVo.setReceiverName(shipping.getReceiverName());
        shippingVo.setReceiverAddress(shipping.getReceiverAddress());
        shippingVo.setReceiverProvince(shipping.getReceiverProvince());
        shippingVo.setReceiverCity(shipping.getReceiverCity());
        shippingVo.setReceiverDistrict(shipping.getReceiverDistrict());
        shippingVo.setReceiverMobile(shipping.getReceiverMobile());
        shippingVo.setReceiverPhone(shipping.getReceiverPhone());
        shippingVo.setReceiverZip(shipping.getReceiverZip());
        return shippingVo;
    }

    //清除购物车方法
    private void cleanCart(List<Cart> cartList) {
        for (Cart cartItem : cartList) {
            cartDao.deleteByPrimaryKey(cartItem.getId());

        }
    }


    //更新库存的方法
    private void reduceProductStock(List<OrderItem> orderItemList) {
        for (OrderItem orderItem : orderItemList) {
            Product product = productDao.selectByPrimaryKey(orderItem.getProductId());
            product.setStock(product.getStock() - orderItem.getQuantity());
            productDao.updateByPrimaryKeySelective(product);
        }
    }


    //组装订单信息（所要下单的订单的信息）payment:支付总金额
    private Order assembleOrder(Integer userId, Integer shippingId, BigDecimal payment) {

        Order order = new Order();
        long orderNo = this.generateOrderNo();
        order.setOrderNo(orderNo);
        order.setStatus(ConstUtil.OrderStatusEnum.NO_PAY.getCode());
        order.setPostage(0);
        order.setPaymentType(ConstUtil.PaymentTypeEnum.ONLINE_PAY.getCode());
        order.setPayment(payment);
        order.setUserId(userId);
        order.setShippingId(shippingId);

        //发货时间
        //付款时间
        int rowCount = orderDao.insert(order);
        if (rowCount > 0) {
            return order;
        }
        return null;
    }


    //生成订单号，利用时间戳和随机数
    private long generateOrderNo() {
        long currentTime = System.currentTimeMillis();
        return currentTime + new Random().nextInt(100);
    }


    //获取订单的总价格
    private BigDecimal getOrderTotalPrice(List<OrderItem> orderItemList) {
        BigDecimal payment = new BigDecimal("0");
        for (OrderItem orderItem : orderItemList) {
            payment = BigDecimalUtil.add(payment.doubleValue(), orderItem.getTotalPrice().doubleValue());
        }
        return payment;
    }


    //获取购物车中订单的信息
    private ResultData getCartOrderItem(Integer userId, List<Cart> cartList) {
        List<OrderItem> orderItemList = Lists.newArrayList();
        if (CollectionUtils.isEmpty(cartList)) {
            return ResultData.fail("购物车为空");
        }

        //校验购物车中的数据，包括产品的数量和状态
        for (Cart cartItem : cartList) {
            OrderItem orderItem = new OrderItem();
            System.out.println("ProductId: " + cartItem.getProductId());
            Product product = productDao.selectByPrimaryKey(cartItem.getProductId());

            if (product == null) {
                System.out.println("空指针异常");
            }


            if (ConstUtil.ProductStatusEnum.ON_SALE.getCode() != product.getStatus()) {
                return ResultData.createData("产品" + product.getName() + "不是在线售卖状态");
            }

            //校验库存
            if (cartItem.getQuantity() > product.getStock()) {
                return ResultData.createData("产品" + product.getName() + "库存不足");
            }

            //设置单一商品的相关信息
            orderItem.setUserId(userId);
            orderItem.setProductId(product.getId());
            orderItem.setProductName(product.getName());
            orderItem.setProductImage(product.getMainImage());
            orderItem.setCurrentUnitPrice(product.getPrice());
            orderItem.setQuantity(cartItem.getQuantity());
            orderItem.setTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(), cartItem.getQuantity()));

            //分别将每个商品的订单信息添加到orderItemList这个List数组里面
            orderItemList.add(orderItem);
        }
        return ResultData.createData(orderItemList);
    }

    //封装一个组装用户订单详情的私有方法
    private List<OrderVo> assembleOrderVoList(List<Order> orderList,Integer userId){
        List<OrderVo> orderVoList = Lists.newArrayList();
        for(Order order : orderList){
            List<OrderItem> orderItemList = Lists.newArrayList();
            if(userId == null){
                //TODO  以管理员的身份去查看订单列表，不需要传userId，因为管理员可以查看每个人的订单
                orderItemList = orderItemDao.getAllByOrderNo(order.getOrderNo());
            }else{
                orderItemList = orderItemDao.getByOrderNoUserId(order.getOrderNo(),userId);
            }
            OrderVo orderVo = assembleOrderVo(order,orderItemList);
            orderVoList.add(orderVo);
        }
        return orderVoList;
    }

    // 管理员层的相关接口实现方法
    @Override
    public ResultData<PageInfo> manageList(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Order> orderList = orderDao.selectAllOrder();

        List<OrderVo> orderVoList = assembleOrderVoList(orderList, null);
        PageInfo pageResult = new PageInfo(orderList);
        pageResult.setList(orderVoList);
        return ResultData.createData(pageResult);
    }


    //后台管理员查看订单详情接口实现
    public ResultData<com.example.front.vo.OrderVo> manageDetail(Long orderNo) {
        Order order = orderDao.selectByOrderNo(orderNo);
        if (order != null) {
            List<OrderItem> orderItemList = orderItemDao.getAllByOrderNo(orderNo);
            OrderVo orderVo = assembleOrderVo(order, orderItemList);
            return ResultData.createData(orderVo);
        }
        return ResultData.fail("订单不存在");
    }


    //后台管理员订单搜索接口实现 (暂时是精确匹配)
    public ResultData<PageInfo> manageSearch(Long orderNo, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Order order = orderDao.selectByOrderNo(orderNo);
        if (order != null) {

            List<OrderItem> orderItemList = orderItemDao.getAllByOrderNo(orderNo);
            OrderVo orderVo = assembleOrderVo(order, orderItemList);
            PageInfo pageResult = new PageInfo(Lists.newArrayList(order));
            pageResult.setList(Lists.newArrayList(orderVo));
            return ResultData.createData(pageResult);
        }
        return ResultData.fail("订单不存在");
    }


    //管理员根据订单号发货接口
    public ResultData<String> manageSendGoods(Long orderNo) {
        Order order = orderDao.selectByOrderNo(orderNo);
        if (order != null) {
            if (order.getStatus() == ConstUtil.OrderStatusEnum.PAID.getCode()) {
                order.setStatus(ConstUtil.OrderStatusEnum.SHIPPED.getCode());
                order.setSendTime(new Date());
                orderDao.updateByPrimaryKeySelective(order);
                return ResultData.success("发货成功");
            }
        }
        return ResultData.fail("订单不存在");
    }
}
